package com.code.thread.deadlock;

import java.util.concurrent.TimeUnit;

public class Philosopher extends Thread {
    private String name;

    private int index ;

    private ChopStick leftChopStick;
    private ChopStick rightChopStick;

    public Philosopher(String name, int index, ChopStick leftChopStick, ChopStick rightChopStick) {
        this.name = name;
        this.index = index;
        this.leftChopStick = leftChopStick;
        this.rightChopStick = rightChopStick;
    }

    @Override
    public void run() {
        /**
         * 解决方案
         * 1、增加大锁
         * 2、默认一个加锁顺序不同
         * 3、偶数加锁顺充不同
         */
//        deadLock();
//        noDead1();
        noDead2();
    }

    public void noDead1() {
        try {
            if (index == 1) {
                synchronized (rightChopStick) {
                    // 这里加sleep 是为了模拟出死销
                    TimeUnit.SECONDS.sleep(index+1);
                    // 这里加sleep 是为了模拟出死销
                    synchronized (leftChopStick) {
                        TimeUnit.SECONDS.sleep(1);
                        System.out.println(name + " is eating");
                    }
                }
            } else {
                synchronized (leftChopStick) {
                    // 这里加sleep 是为了模拟出死销
                    TimeUnit.SECONDS.sleep(index+1);
                    // 这里加sleep 是为了模拟出死销
                    synchronized (rightChopStick) {
                        TimeUnit.SECONDS.sleep(1);
                        System.out.println(name + " is eating");
                    }
                }
            }

        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    public void noDead2() {
        try {
            if (index % 2 == 0) {
                synchronized (rightChopStick) {
                    // 这里加sleep 是为了模拟出死销
                    TimeUnit.SECONDS.sleep(index+1);
                    // 这里加sleep 是为了模拟出死销
                    synchronized (leftChopStick) {
                        TimeUnit.SECONDS.sleep(1);
                        System.out.println(name + " is eating");
                    }
                }
            } else {
                synchronized (leftChopStick) {
                    // 这里加sleep 是为了模拟出死销
                    TimeUnit.SECONDS.sleep(index+1);
                    // 这里加sleep 是为了模拟出死销
                    synchronized (rightChopStick) {
                        TimeUnit.SECONDS.sleep(1);
                        System.out.println(name + " is eating");
                    }
                }
            }

        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    public void deadLock() {
        try {
            synchronized (leftChopStick) {
                // 这里加sleep 是为了模拟出死销
                TimeUnit.SECONDS.sleep(index+1);
                // 这里加sleep 是为了模拟出死销
                synchronized (rightChopStick) {
                    TimeUnit.SECONDS.sleep(1);
                    System.out.println(name + " is eating");
                }
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}
